package com.simple.microservices.service.auth;


import cn.dev33.satoken.session.TokenSign;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.simple.microservices.api.auth.AuthService;
import com.simple.microservices.api.dto.LoginDTO;
import com.simple.microservices.commons.constant.CommonConstant;
import com.simple.microservices.commons.constant.LoginConstant;
import com.simple.microservices.commons.exceptions.BusinessException;
import com.simple.microservices.commons.token.dto.Token;
import com.simple.microservices.commons.utils.CommonRequestUtils;
import com.simple.microservices.dao.dataobject.Member;
import com.simple.microservices.dao.mapper.MemberMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import static com.simple.microservices.commons.constant.LoginConstant.LOGIN_TYPE;
import static com.simple.microservices.commons.constant.LoginConstant.USER_TOKEN_KEY;

/**
 * 授权服务实现类
 *
 * @author HYF
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    @Qualifier("redis")
    private RedisTemplate redis;

    @Value("${sa-token.timeout}")
    private Long timeout;
    @Value("${spring.profiles.active}")
    private String active;

    @Resource
    private MemberMapper memberMapper;

    @Override
    public String login(LoginDTO loginDTO) {
        StpLogic stpLogic = new StpLogic(loginDTO.getIdentityType());
        StpUtil.setStpLogic(stpLogic);
        String device = CommonRequestUtils.getDevice();
        if (StringUtils.isNotEmpty(device)) {
            //不同设备登录
            StpUtil.login(loginDTO.getCellphone(), device);
        } else {
            StpUtil.login(loginDTO.getCellphone());
        }
        String token = StpUtil.getTokenValueByLoginId(loginDTO.getCellphone());
        String accountId = loginDTO.getAccountId();
        Token tk = new Token(loginDTO.getCellphone(),LOGIN_TYPE,token);
        redis.opsForValue().set(String.format(USER_TOKEN_KEY, token), tk, timeout, TimeUnit.SECONDS);
        return token;
    }

    @Override
    public String login(String cellphone,Long userId) {
        StpUtil.login(userId);
        String token = StpUtil.getTokenValueByLoginId(userId);
//        Token tk = new Token(cellphone,LOGIN_TYPE,token);
//        redis.opsForValue().set(String.format(USER_TOKEN_KEY, token), tk, timeout, TimeUnit.SECONDS);
        return token;
    }

    @Override
    public Member findMemberByCellphone(String cellphone) {
        LambdaQueryWrapper<Member> memberLambdaQueryWrapper = new LambdaQueryWrapper<>();
        memberLambdaQueryWrapper.eq(Member::getCellphone, cellphone);
        Member member = memberMapper.selectOne(memberLambdaQueryWrapper);
        return member;
    }

    @Override
    public void saveMember(Member req) {
        memberMapper.insert(req);
    }

    @Override
    public Boolean checkCode(String cellphone, String code) {
        Object obj = redis.opsForValue().get(String.format(LoginConstant.CELLPHONE_MESSAGE_CODE, LoginConstant.MESSAGE_TYPE_LOGIN, cellphone));
        if (ObjectUtils.isEmpty(obj)) {
            throw new BusinessException("验证码已过期");
        } else if (obj.toString().equals(code)) {
            redis.delete(String.format(LoginConstant.CELLPHONE_MESSAGE_CODE, LoginConstant.MESSAGE_TYPE_LOGIN, cellphone));
            return true;
        } else {
            return false;
        }
    }

    @Override
    public void sendCode(String cellphone) {
        String code = "123456";
        if (!active.equals(CommonConstant.PROFILES_DVE)){
            code = getRandomNumCode(6);
        }
        redis.opsForValue().set(String.format(LoginConstant.CELLPHONE_MESSAGE_CODE, LoginConstant.MESSAGE_TYPE_LOGIN, cellphone), code, 5, TimeUnit.MINUTES);

    }

    public static String getRandomNumCode(int number) {
        String codeNum = "";
        int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        Random random = new Random();
        for (int i = 0; i < number; i++) {
            int next = random.nextInt(10000);//目的是产生足够随机的数，避免产生的数字重复率高的问题
//    			System.out.println(next);
            codeNum += numbers[next % 10];
        }
        System.out.println("--------");
        System.out.println(codeNum);

        return codeNum;
    }

}